Skip to main content

Publish Azure Function App

Publish Instructions

This document describes how to publish/deploy an Azure Function App and some common issues that might be encountered during the publishing/deploying process.

  1. If the Function App doesn't exist in the Azure Portal, then create it.
  2. Go to the Function App in the Portal and click "Get publish profile".
  3. Also in the Portal, navigate to Configuration > General settings and ensure the bitness is set to 64. This is critical for Function apps that utilize C++ DLLs (such as SWC Worker).
  4. Open the Function App in Visual Studio (not Code).
  5. Right-click on the Function project and select "Publish"
  6. Choose to import a profile and navigate to the profile you downloaded from the Portal.
  7. Under Settings, choose "Show all settings".
  8. Ensure the following settings are configured (critical for apps utilizing C++ DLLs):
    • Configuration: Release | x64
    • Deployment mode: Framework-dependent
    • Target runtime: win-x64
  9. Click publish.
  10. In the portal, you can watch a log stream of the Function stdout by going to Monitoring > Log stream.

CI/CD Notes

During SWMM development in 2025, Jake attempted configuring the worker function to publish via GitHub Actions CI/CD. This proved to be quite difficult, and so the normal manual publishing approach was adopted instead. Some things to consider for a CI/CD workflow:

  • Only files in the repository are available by default, so any C# applications that have external dependencies (which is essentially all of GQC's C# projects) require additional clones.
  • To clone extra repositories, you need to either configure a Personal Access Token (PAT) or SSH Key.
    • The token/key must be generated
    • It must be added to the CI/CD repository's secrets
    • It must be properly referenced in the workflow YAML file

Here's the latest version of the CI/CD Workflow YAML file that I had tested, but failed to compile:

# Docs for the Azure Web Apps Deploy action: https://github.com/azure/functions-action
# More GitHub Actions for Azure: https://github.com/Azure/actions

name: Build and deploy dotnet core app to Azure Function App - swmm-worker-function

on:
push:
branches:
- main
workflow_dispatch:

env:
AZURE_FUNCTIONAPP_PACKAGE_PATH: '.' # set this to the path to your web app project, defaults to the repository root
DOTNET_VERSION: '8.0.x' # set this to the dotnet version to use

jobs:
build-and-deploy:
runs-on: windows-latest
permissions:
id-token: write #This is required for requesting the JWT
contents: read #This is required for actions/checkout

steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@v4

- name: 'Checkout swmm5_core repository'
uses: actions/checkout@v4
with:
repository: 'gqc/swmm5_core'
path: 'swmm5_core'
token: ${{ secrets.GH_AUTH_TOKEN }}

- name: 'Checkout swc-worker-function repository'
uses: actions/checkout@v4
with:
repository: 'gqc/swc-worker-function'
path: 'swc-worker-function'
token: ${{ secrets.GH_AUTH_TOKEN }}

- name: Setup DotNet ${{ env.DOTNET_VERSION }} Environment
uses: actions/setup-dotnet@v1
with:
dotnet-version: ${{ env.DOTNET_VERSION }}

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1.3

- name: 'Resolve Project Dependencies Using Dotnet'
shell: pwsh
run: |
pushd './${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}'
# Build swmm5_core C# projects first
dotnet build ./swmm5_core/GqcStorage1/GqcStorage1.csproj --configuration Release
dotnet build ./swmm5_core/SwmmModels/SwmmModels.csproj --configuration Release
# Build swc-worker-function project
dotnet build ./swc-worker-function/SwmmWrapper/SwmmWrapper.csproj --configuration Release
# Build swmm5_core C++ projects using MSBuild
msbuild ./swmm5_core/SWMM_Bridge/SWMM_Bridge_64.vcxproj /p:Configuration=Release /p:Platform=x64
msbuild ./swmm5_core/SWMM_Bridge/SWMM_Engine_64.vcxproj /p:Configuration=Release /p:Platform=x64
msbuild ./swmm5_core/Swmm5_Parallel/swmm5_Parallel_64.vcxproj /p:Configuration=Release /p:Platform=x64
# Build main project with all dependencies
dotnet build --configuration Release --output ./output
popd

- name: Login to Azure
uses: azure/login@v2
with:
client-id: ${{ secrets.AZUREAPPSERVICE_CLIENTID_32E9AC1A853342B6B9BA9B89B31A0D8E }}
tenant-id: ${{ secrets.AZUREAPPSERVICE_TENANTID_C9C6404E9FC14C5F974D1DDC7471A287 }}
subscription-id: ${{ secrets.AZUREAPPSERVICE_SUBSCRIPTIONID_B0E79AFE9EDE476D9A489CDC341502EE }}

- name: 'Run Azure Functions Action'
uses: Azure/functions-action@v1
id: fa
with:
app-name: 'swmm-worker-function'
slot-name: 'Production'
package: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/output'